/**********************************************************
	FileName:	kmy350.c
	Describe:	kmy 350 Test
	Author:		lihaitao
	Date:		2007.3.25
***********************************************************/
 
#include     <stdio.h>      
#include     <stdlib.h>     
#include     <unistd.h>     
#include     <fcntl.h>      
#include     <termios.h>    
#include     <errno.h>      

#include <time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "Des.c"


int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
                    B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300,
                  38400,  19200,  9600, 4800, 2400, 1200,  300, };

#define FALSE 0
#define TRUE 1
#define ERR_SEND 1
#define ERR_RECV 1
#define COMTIMEOUT 30000      
#define InfoLen  128


char message[90];
char ErrorInfo[InfoLen] = {0};				

int DesOr3DesMode = 1;			
int MainKeyDownFlag = 0;		
int EncryptWorkMode = 0;		

int fd=0;
int mPinLenMax = 6;			

#if 1

int ReadIniFileString(char *sItemName,char *sKeyName,char *sDesBuffer,char *sFilePath)
{
	FILE *pFile;
	char sRight[1024] ="";
	char *pRight = NULL;
	char *pStr = NULL;
	char *p=NULL;
	int skeylen;
	char sRightItemString[1024] = "";
	int k = 0;
	int i = 0;

	char sItem[20] = "";
	sprintf(sItem,"[%s]",sItemName);

	pFile=fopen(sFilePath,"rb");
	if(pFile)
	{
		fread(sRight,1024,1,pFile);

		pStr = strstr(sRight,sItem);
		if(!pStr)
			return 1;				

		pStr = pStr + strlen(sItem);

		
		while((*pStr) != '\0' && (*pStr) != '[')
		{
			sRightItemString[k] = *pStr;
			pStr++;
			k++;
		}
		pStr = strstr(sRightItemString,sKeyName);
		if(!pStr) return 1;				

		skeylen = strlen(sKeyName);
		
		p = pStr + skeylen;

		while((*p)!='\n' && (*p)!='\0'){
			if((*p) != ' ' && (*p) != '='){
				pRight = p;
				break;
			}
			p++;
		}

		if(*pRight != '\n' && *pRight != '\0'){
			while((*pRight) != '\n' && (*pRight) != '\0'){
				sDesBuffer[i] = *pRight;
				pRight ++;
				i ++;
			}
			sDesBuffer[i] = '\0';
		}else return 1;			
		fclose(pFile);
		return 0;					
	}
	else return 1;					
}	

void set_speed(int fd, int speed)
{
    int   i;
    int   status;
    struct termios   Opt;
    
    sprintf(message,"Baud_Rate=%i \r\n",speed);
        
    tcgetattr(fd, &Opt);    
    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
    {
        if  (speed == name_arr[i])
        {
            tcflush(fd, TCIOFLUSH);     
            cfsetispeed(&Opt, speed_arr[i]);
            cfsetospeed(&Opt, speed_arr[i]);
            status = tcsetattr(fd, TCSANOW, &Opt);
            if  (status != 0)
                perror("tcsetattr fd1");
                return;
            }
            tcflush(fd,TCIOFLUSH);
        }
    }


int set_Parity(int fd,int databits,int stopbits,int parity)
{
    struct termios   options;
	
    sprintf(message,"Data Bits=%i  Stop Bits=%i  Parity=%i \r\n",databits, stopbits, parity);
    printf(message);

    if  ( tcgetattr( fd,&options)  !=  0)
    {
        perror("SetupSerial 1");
        return 1; 
    }
    options.c_cflag &= ~CSIZE;
    switch (databits) 
    {
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            fprintf(stderr,"Unsupported data size\n");
            return 1; /*(FALSE);*/
    }
    switch (parity)
    {
        case 'n':
        case 'N':
            options.c_cflag &= ~PARENB;        	//Clear parity enable 
            options.c_iflag &= ~INPCK;         	//Enable parity checking
            break;
        case 'E':
			options.c_cflag |= PARENB;     		// Enable parity  
			options.c_cflag &= ~PARODD;   		
			options.c_iflag |= INPCK;       	// Disnable parity checking 
		break;
        default:
            fprintf(stderr,"Unsupported parity\n");
            return 1; /*(FALSE);*/
    }

    switch (stopbits)
    {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
        case 2:
            options.c_cflag |= CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return 1;/*(FALSE);*/
    }

    options.c_cc[VTIME] = 0;//150; // 15 seconds
    options.c_cc[VMIN] = 0;
    //options.c_cc[VMIN] = 1;                  
    tcflush(fd,TCIFLUSH);                      //Update the options and do it NOW

    options.c_lflag &=~(ICANON | ECHO | ECHOE | ISIG | IEXTEN);
    options.c_iflag &=~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    options.c_oflag &=~(OPOST);

    if (tcsetattr(fd,TCSANOW,&options) != 0)   
    {
        perror("SetupSerial 3");
        return 1;/*(FALSE);*/
    }
    
    tcflush(fd,TCIOFLUSH);

    return 0;/*(TRUE);*/
}

/**

*/
int OpenDev(char *Dev)
{
	int fd;

	// sprintf(message,"\nDevice=%s\n",Dev); 
	//printf(message);
    
	fd = open(Dev, O_RDWR | O_NOCTTY|O_NDELAY);

	if (-1 == fd)
	{ 
		perror("Can't Open Serial Port\n");
		return 1;
	}
	else
	{
		//printf("Open Serial Port:%s OK!\n",Dev);
		return fd;
	}
    
	ioctl(fd,TIOCCONS);
}

/* write the users command out the serial port */
int KmyComSend_cmd(int fd, char * str, int iLen)
{
    int result,i;
    result = write(fd,str,iLen);
    if (result < 0)
	{
		sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}
    else
    {
		//printf("\nWrite Command:\n");
		//for (i=0;i<iLen;i++)
		//    printf("Data:%x\n",str[i]);
		//printf("\nWrite Command Port Ok!\n");
		return 0;
    }
}

int KmyComRcvByLen(int iPortFd,char * cpSendBuf,int iLen)
{
    int i=0,ret=0;

    clock_t start, finish,internalTime;
    internalTime=COMTIMEOUT*1000;        
    start=clock();
    
	if (iPortFd <= 0 )
	{
		sprintf(ErrorInfo,"Please Open Comm Port"); 
		return 1;
	} 
	
    while(1)
    {
        KmyDelay(10);
        ret=read(iPortFd, (cpSendBuf+i), 1);
        if(ret!=1)
		{
	    	finish=clock();
	    	if((finish-start)>internalTime)
	    	{
	        	sprintf(ErrorInfo,"com rcv len time out"); 
	        	tcflush(iPortFd, TCIOFLUSH); 	
				return ERR_RECV;
	    	}
			continue;
		}
		//printf("recv data,hex=%02x,chr mod=%c,alr rcv��%d,iLen=%d\r\n",*(cpSendBuf+i),*(cpSendBuf+i),i,iLen);	
		i++;
				
		fflush(stdout);
			
		if(i==iLen)
		{
			tcflush(iPortFd, TCIOFLUSH); 	
			break;
		}
	}
	return 0;
}

int KmyComRcvByDataLen(int iPortFd,char * cpSendBuf,int * iLen)
{
    int i=0,ret=0;
    int iTmpLen=0;
    char cpLen[3];

    clock_t start, finish,internalTime;
    internalTime=COMTIMEOUT*1000;        
    start=clock();
    
	if (iPortFd <= 0 )
	{
		sprintf(ErrorInfo,"Please Open Comm Port"); 
		return 1;
	}    
	
    while(1)
    {
        KmyDelay(10);
        ret=read(iPortFd, (cpSendBuf+i), 1);
        if(ret!=1)
		{
	    	finish=clock();
	    	if((finish-start)>internalTime)
	    	{
	        	sprintf(ErrorInfo,"com rcv len time out"); 
	        	tcflush(iPortFd, TCIOFLUSH); 	
				return ERR_RECV;
	    	}
			continue;
		}
		//printf("recv data,hex=%02x,chr mod=%c,alr rcv��%d\r\n",*(cpSendBuf+i),*(cpSendBuf+i),i);	
		i++;
				
		fflush(stdout);
			
		if (i==3)
		{
			cpLen[0] = cpSendBuf[1];
			cpLen[1] = cpSendBuf[2];
			cpLen[2] = 0x00;
			iTmpLen = HexToLen(cpLen);			
			//printf("iLen = %d\n",iTmpLen);
		}
		
		if (i==iTmpLen*2+5)
		{
			tcflush(iPortFd, TCIOFLUSH); 		
			*iLen = i;
			break;
		}
	}
	return 0;
}
#endif
int HexToLen(char *chIn)
{
    short len,offset;
	short nLen;

    len = strlen(chIn);
	int lOut = 0;
	int i=0;

	for(i=0;i<len;i++)
	{
		if( chIn[i]!=0x30 )
			break;
	}
	offset = i;  

	for(i=offset;i<len;i++)
	{
       if((chIn[i]>='A')&&(chIn[i]<='F'))
	        chIn[i] = chIn[i]-'A'+10;
	   else
		    chIn[i] = chIn[i]-'0';

        nLen = chIn[i]/16*10 + chIn[i]%16;
        lOut = lOut*16 + nLen;
	}

    return lOut;
}

void LenToHex(char *chLen, int nLen)
{
    int i;
    sprintf(chLen,"%02X",nLen);

    for( i= 0;i<2;i++)
    {
        if( chLen[i] == 'a' )
            chLen[i] = 'A';
        if( chLen[i] == 'b' )
            chLen[i] = 'B';
        if( chLen[i] == 'c' )
            chLen[i] = 'C';
        if( chLen[i] == 'd' )
            chLen[i] = 'D';
        if( chLen[i] == 'e' )
            chLen[i] = 'E';
	if( chLen[i] == 'f' )
	    chLen[i] = 'F';
    }
    chLen[2]='\0';
}


int KmyComRcvBySpcStr(int iPortFd,char * cpSendBuf,int * iLen,char * cSpeChar)
{
	int i=0,ret=0;
	clock_t start, finish,internalTime;
	internalTime=COMTIMEOUT*1000;
	start=clock();
	
	if (iPortFd <= 0 )
	{
		sprintf(ErrorInfo,"Please Open Comm Port"); 
		return 1;
	}	
	
	while(1)
	{
		KmyDelay(10);

		ret=read(iPortFd, (cpSendBuf+i), 1);
		if(ret!=1)
		{
			finish=clock();
			if((finish-start)>internalTime)
			{
				sprintf(ErrorInfo,"com rcv Spc time out"); 
				tcflush(iPortFd, TCIOFLUSH); 	
				return ERR_RECV;
			}
			continue;
		}
		//printf("recv data,hex=%02x,chr mod=%c,alr rcv��%d\r\n",*(cpSendBuf+i),*(cpSendBuf+i),i);	
		//if(*(cpSendBuf+i)==cSpeChar)
		if (strstr(cpSendBuf,cSpeChar))
		{
			i++;
			*iLen=i;			
			tcflush(iPortFd, TCIOFLUSH); 		
			break;
		}
		i++;
		
	}
	return 0;
}

int KmyDelay(int iHM)
{
	clock_t start, finish,internalTime;
	
	internalTime=iHM*1000;
	start=clock();
	while(1)
	{
		finish=clock();
		if((finish-start)>internalTime)
		{
			break;
		}
	}	
}

/**
*@breif         OpenComm()
*return 		1:ERROR, 0:OK
*/
int OpenComm(const char* Com, int Baudrate, int Parity, int StopBits, int DataBits)
{
	const char *dev = Com;       
	int retu = 1;
	int iret;
	fd = OpenDev(dev);
    if (fd > 0)
    {
    	char parity = 'N';
    	switch(Parity) {
        case 0:
        	parity = 'N';
        	break;
        case 1:
        	parity = 'E';
        	break;
        case 2:
        	parity = 'O';
        break;
    	}
    	set_speed(fd,Baudrate);
    	if (set_Parity(fd,DataBits,StopBits,parity) == 1) {
        sprintf(stdout,"Set Com Value Error");
        fflush(stdout);
    	}
    	else
        retu = 0;
    }
    else
    {
    	sprintf(stdout,"Can't Open Serial Port!");  
    	fflush(stdout);
    	retu = 1;                
    }
	return retu;
}

int ResetSelfCheck()
{
	int iretu;
	char ENDCHAR[3]={0x30,0x35,0x00};
	char buff[512];
	int i;
    char chCommand[256],chSendCmd[256];
    int nLen,ret;

    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);

    sprintf(chCommand,"%02X",0x01);
    sprintf(chCommand+2,"%02X",0x31);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}    

	iretu = KmyComRcvBySpcStr(fd,buff,&i,ENDCHAR);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"com rcv Spc time out"); 
		return 1;
	}  	
    return 0;
}

int ResetAndSetPin()
{
	int iretu;
	char ENDCHAR[3]={0x30,0x35,0x00};
    char chCommand[256],chSendCmd[256];
    char buff[512];
    int i;
    int nLen,ret;

    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);

    sprintf(chCommand,"%02X",0x02);
    sprintf(chCommand+2,"%02X",0x31);  
	sprintf(chCommand+4,"%02X",0x38);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}    

	iretu = KmyComRcvBySpcStr(fd,buff,&i,ENDCHAR);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"com rcv Spc time out"); 
		return 1;
	}  	
    return 0;    
}


//��if sour=0x39 0x30" then return =0x90
char asc_to_bcd(char *sour)
{
	char HBits = sour[0];
	//WriteLogInt("HBits=",HBits); 
	
	if ((HBits >= 65) && (HBits <= 70)) HBits -= 7;		//for A--F
	if ((HBits >= 97) && (HBits <= 102)) HBits -= 39;	//for a--f
	if ((HBits - 0x30) > 0x0f) HBits = 0x30;
	else if ((HBits - 0x30) < 0x00) HBits = 0x30;
	HBits = (HBits - 0x30) * 0x10;
	
	char LBits = sour[1];
	//WriteLogInt("LBits=",LBits); 
	
	if ((LBits >= 65) && (LBits <= 70)) LBits -= 7;		//for A--F
	if ((LBits >= 97) && (LBits <= 102)) LBits -= 39;	//for a--f
	if ((LBits - 0x30) > 0x0f) LBits = 0x30;
	else if ((LBits - 0x30) < 0x00) LBits = 0x30;
	LBits = (LBits - 0x30);
	
	char bcd = HBits + LBits;
	
	return bcd;
}

int GetDeviceNo(char *cpNoBuf)
{
	int iretu;
	char chCommand[256],chSendCmd[256];
    char buff[512];
    int i;
    int nLen,ret;

    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);
    memset(buff,'\0',512);

    sprintf(chCommand,"%02X",0x01);
    sprintf(chCommand+2,"%02X",0x38);  

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}   

    iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"com rcv len time out"); 
		return 1;
	}
	else
	{
    	memcpy(cpNoBuf,buff+5,i);
        cpNoBuf[i]=0;
    	return 0;
    }
}

int GetVer(char *cpRevBuf)
{
	int iretu;
    char chCommand[256],chSendCmd[256];
    char buff[512];
    int i;
    int nLen,ret;
    char pTmp[512];

    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);
    memset(buff,'\0',512);
    memset(pTmp,'\0',512);

    sprintf(chCommand,"%02X",0x01);
    sprintf(chCommand+2,"%02X",0x30);  

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	} 

	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"com rcv len time out"); 
		return 1;
	}
    else
    {
    	memcpy(pTmp,buff+5,i-19);
        pTmp[i-19]=0;
        //printf("==%s\n",pTmp);
        CompressAsc(pTmp,i-19,cpRevBuf);
    	return 0;
    }
}

int SetDesOr3Des()
{
	int iretu;
	char chCommand[256],chSendCmd[256];
    char buff[512];
    int Mode;
    int i;
    int nLen,ret,p;
    char pTmp[512];
    
	if(EncryptWorkMode==0)
	{
		//Des
		Mode=0x20;		
		p=0x00;
	}
	else if(EncryptWorkMode==1)
	{
		//3Des
		Mode=0x30;		
		p=0x00;
	}
	
    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);
    memset(buff,'\0',512);
    memset(pTmp,'\0',512);

    sprintf(chCommand,"%02X",0x03);
    sprintf(chCommand+2,"%02X",0x46);
    sprintf(chCommand+4,"%02X",p);
    sprintf(chCommand+6,"%02X",Mode);    

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		sprintf(ErrorInfo,"Set Load Wkey Enc Mode Fail-Write command to Comm failed");  
		return 1;
	} 
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Load Wkey Enc Mode Fail-com rcv by len time out");
		return 1;
	}
    
	if(EncryptWorkMode==0)
	{
		//Des
		Mode=0x20;		
		p=0x01;
	}
	else if(EncryptWorkMode==1)
	{
		//3Des
		Mode=0x30;		
		p=0x01;
	}
	
    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);
    memset(buff,'\0',512);
    memset(pTmp,'\0',512);

    sprintf(chCommand,"%02X",0x03);
    sprintf(chCommand+2,"%02X",0x46);
    sprintf(chCommand+4,"%02X",p);
    sprintf(chCommand+6,"%02X",Mode);    

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}

int CompressAsc(char *soustr, int len, char *desstr)
{
    int i=0;
	int ch;
    char tmpstr[2049];

    sprintf( tmpstr, "%*.*s", len, len, soustr );
    for( i=0; i<(len+1)/2; i++ )
    {
	    sscanf( tmpstr+i*2, "%02X", &ch );
	    desstr[i] = ch & 0xFF;
    }
    desstr[i] ='\0';
    return 0;
}

int BCC(char *buffer, int count)
{
    int           i, bcccalc, ch;
    bcccalc = 0;
    for(i = 0; i < count; i++ )
    {
	    sscanf( buffer+i*2, "%02X", &ch );
	    bcccalc ^= ch;
    }
    return(bcccalc);
}

char *SplitBcd(char *soustr, int len, char *desstr)
{
    int i;

    strcpy( desstr, "" );
    for( i=0; i<len; i++ )
    {    
		sprintf( desstr, "%s%02X", desstr, soustr[i]&0XFF );
	    desstr+=2;
    }
    return desstr;
}


int LoadMasterKey(int MKeyNo, char *MKeyAsc)
{
	int iretu;
    char chCommand[256],chSendCmd[256],DataBcd[256];

    int   nLen, ret, i;
    char  MKeyAsc8[9];
    
    char buff[512];
    
    iretu = SetDesOr3Des();
    if (iretu) 
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail�");
		return 1;
	}
	
	if((MKeyNo > 15) || (MKeyNo < 0))
	{
		sprintf(ErrorInfo,"Mkey ID Error!");
		return 1;			
	}
	
    memset(chSendCmd,'\0',256);
    memset(chCommand,'\0',256);


    memset(MKeyAsc8,'\0',9);
    memcpy(MKeyAsc8,MKeyAsc,8);

	if(EncryptWorkMode==1)			//3DES
	{
	    sprintf(chCommand,"%02X",0x12);
	    sprintf(chCommand+2,"%02X",0x32);
	    sprintf(chCommand+4,"%02X",MKeyNo);
    }

	if(EncryptWorkMode==0)			//DES
	{
	    sprintf(chCommand,"%02X",0x0A);
	    sprintf(chCommand+2,"%02X",0x32);
	    sprintf(chCommand+4,"%02X",MKeyNo);
    }

    nLen=strlen(MKeyAsc);
	if((nLen!=8)&&(nLen!=16)&&(nLen!=32))
	{
		return 1;
	}

	if(EncryptWorkMode==0)			//DES
	{
		if (nLen==16) 
		{
			memcpy(chCommand+6,MKeyAsc,16);
		}
		else
		{
			SplitBcd(MKeyAsc,8,DataBcd);
			strcpy(chCommand+6,DataBcd);
		}
	}
	else if(EncryptWorkMode==1)		//3DES
	{
		if (nLen==32) 
		{
			memcpy(chCommand+6,MKeyAsc,32);
		}
		else
		{
			SplitBcd(MKeyAsc,16,DataBcd);
			strcpy(chCommand+6,DataBcd);
		}
	}
    
    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );


	sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}

int gDes( char *DataInput,char *key, char *DataOutput)
{
	char  DataBcd[128],tmp[128],KeyBcd[128];
	int nLen;

	memset( KeyBcd,'\0',128 );
	memset( DataBcd,'\0',128 );
	memset( tmp,'\0',128 );
    nLen=strlen(DataInput);
    if (nLen==16) 
	{
		CompressAsc(DataInput, 16, DataBcd);
    }
    else
	{
		memcpy(DataBcd,DataInput,8);
    }

	nLen = strlen( key );
    if (nLen==16) 
	{
		CompressAsc(key, 16, KeyBcd);
    }
    else
	{
		memcpy(KeyBcd,key,8);
    }
    Des( (unsigned char *)DataBcd,(unsigned char *)KeyBcd, (unsigned char *)tmp);
	SplitBcd(tmp, 8, DataOutput);
	return 0;
}

int gTriDes( char *DataInput,char *key, char *DataOutput)
{
	char  DataBcd[128]={0},tmp[128]={0},left[20]={0},right[20]={0},tmp1[128]={0},tmp2[128]={0};
	int nLen;

	if (strlen(key)==32)
	{
        char cpLeft[17]={0},cpRight[17]={0};
        memcpy( cpLeft,key,16 );
		memcpy( cpRight,key+16,16 );
		CompressAsc(cpLeft,16,left);
		CompressAsc(cpRight,16,right);
	}
	else
	{
		memcpy(left,key,8);
		memcpy(right,key+8,8);
	}

    nLen=strlen(DataInput);
    if (nLen==16) 
	{
		CompressAsc(DataInput, 16, DataBcd);
    }
    else
	{
		memcpy(DataBcd,DataInput,8);
    }
    Des( (unsigned char *)DataBcd,(unsigned char *)left, (unsigned char *)tmp1);
	Undes( (unsigned char *)tmp1,(unsigned char *)right, (unsigned char *)tmp2);
	Des( (unsigned char *)tmp2,(unsigned char *)left, (unsigned char *)tmp);
	SplitBcd(tmp, 8, DataOutput);
	return 0;
}

int LoadWorkKey(int MKeyNo, int WKeyNo, char *WKeyAsc)
{
	int iretu;
	char chCommand[256],chSendCmd[256],DataBcd[256];

    int   i,nLen,ret;

	char buff[512] = {0};
	
    iretu = SetDesOr3Des();
    if (iretu) 
	{
		sprintf(ErrorInfo,"Set Enc Mode Fail!");
		return 1;
	}

	if((MKeyNo > 15) || (MKeyNo < 0))
	{
		sprintf(ErrorInfo,"Mkey ID Error!");
		return 1;			//��ֹ������������
	}
	
	if((WKeyNo > 15) || (WKeyNo < 0))
	{
		sprintf(ErrorInfo,"Wkey ID Error!");
		return 1;			
	}	

    memset(chSendCmd,'\0',256);
    memset(chCommand,'\0',256);

	if(EncryptWorkMode == 1)			//3DES
	{
	    sprintf(chCommand,"%02X",0x13);			
	    sprintf(chCommand+2,"%02X",0x33);
	    sprintf(chCommand+4,"%02X",MKeyNo);		
	}

    if(EncryptWorkMode == 0)			//DES
	{
	    sprintf(chCommand,"%02X",0x0B);			
	    sprintf(chCommand+2,"%02X",0x33);
	    sprintf(chCommand+4,"%02X",MKeyNo);		
	}

    sprintf(chCommand+6,"%02X",WKeyNo);			
    //strcpy(chCommand2,WKeyAsc);

    nLen=strlen(WKeyAsc);
	if((nLen != 8)&&(nLen != 16)&&(nLen != 32))
	{
		sprintf(ErrorInfo,"Wkey Len Error!");
		return 1;//ERR_PINMODE;
	}

	if(EncryptWorkMode == 0)		//DES
	{
		if (nLen==16) 
		{
			memcpy(chCommand+8,WKeyAsc,16);		
		}
		else					
		{
			SplitBcd(WKeyAsc,8,DataBcd);
			strcpy(chCommand+8,DataBcd);
		}
	}else if(EncryptWorkMode == 1)		//3DES
	{
		if (nLen==32) 
		{
			memcpy(chCommand+8,WKeyAsc,32);		
		}
		else						//���ȣ�8
		{
			SplitBcd(WKeyAsc,16,DataBcd);
			strcpy(chCommand+8,DataBcd);
		}
	}

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );

	sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
	
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Load Wkey Fail-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Load Wkey Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}


int ActivWorkPin(int MKeyNo, int WKeyNo)
{
	int iretu;
    char chCommand[256],chSendCmd[256];

    int   nLen, ret, i;
    
    char buff[512] = {0};
	
	if((MKeyNo > 15) || (MKeyNo < 0))
	{
		sprintf(ErrorInfo,"MKey ID Error!");
		return 1;			
	}
	
	if((WKeyNo > 15) || (WKeyNo < 0))
	{
		sprintf(ErrorInfo,"Wkey ID Error");
		return 1;			
	}	

    memset(chSendCmd,'\0',256);
    memset(chCommand,'\0',256);

    sprintf(chCommand,"%02X",0x03);
    sprintf(chCommand+2,"%02X",0x43);
    sprintf(chCommand+4,"%02X",MKeyNo);
    sprintf(chCommand+6,"%02X",WKeyNo);
    
    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );


	sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Active Wkey Fail-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Active Wkey Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}

int SetPinLen(int iLen)
{
	if (iLen == 0)
	{
		sprintf(ErrorInfo,"Set Pin Len Fail!");
		return 1;
	}
	mPinLenMax = iLen;
	return 0;
}

int OpenKeyVoic(int CTL)
{
	int iretu;
    char chCommand[100],chSendCmd[256];
    int  nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);

    sprintf(chCommand,"%02X",0x02);
    sprintf(chCommand+2,"%02X",0x45);
    sprintf(chCommand+4,"%02X",CTL);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );

    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Fail-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Set Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}

int PinLoadCardNo(char *pchCardNo)
{
	int iretu;
    char  chCommand[100],chSendCmd[256];
    long  TimeNow,TimeCurr;
    int   i,nLen,ret;
    char  CardNoAsc[25],CardNoBcd[13];
    char  bCard[13];
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);
    memset(CardNoAsc,'\0',25);
    memset(CardNoBcd,'\0',13);
    
    if (strlen(pchCardNo) <= 12)		
	{
		sprintf(ErrorInfo,"Car lose 13bit");
		return 1;
	}
	
	memset(bCard,'\0',13);
	memcpy(bCard,pchCardNo + (strlen(pchCardNo)-13),12);

    sprintf(chCommand,"%02X",0x0D);
    sprintf(chCommand+2,"%02X",0x34);

    nLen=strlen(pchCardNo);
	SplitBcd(pchCardNo, 12, CardNoAsc);
	strcpy(chCommand+4, CardNoAsc);
	
	nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );

    sprintf( chSendCmd, "%c%s%02X", 0x02, chCommand, ret );
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Load Car Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Load Car Fail-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}

int PinStartAdd(short PinLen, short DispMode, short AddMode, short PromMode, short nTimeOut)
{
	int  iretu;
    char  chCommand[100],chSendCmd[256];
    long  TimeCurr, TimeNow;
	int   i;
    int   nLen,ret;
    short RcvPurDataLen;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);

    sprintf(chCommand,"%02X",0x06);
    sprintf(chCommand+2,"%02X",0x35);
    sprintf(chCommand+4,"%02X",PinLen);
    sprintf(chCommand+6,"%02X",DispMode);
    sprintf(chCommand+8,"%02X",AddMode);
    sprintf(chCommand+10,"%02X",PromMode);
    sprintf(chCommand+12,"%02X",nTimeOut);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );

    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Input Pw Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Input Pw Fail-com rcv Spc time out");
		return 1;
	}
	else
    	return 0;
}

int PinEnableMode(char *pchCardNo)
{
    int iretu;
    int timeOut = 20;
    
    iretu = OpenKeyVoic(1);
	if( iretu )
	{
		sprintf(ErrorInfo,"Fail");
		return 1;
	}

	iretu = PinLoadCardNo( pchCardNo );  
	if( iretu )
	{
		sprintf(ErrorInfo,"Input Fail");
		return 1;
	}
	iretu = PinStartAdd(mPinLenMax,1,1,0,timeOut);     //�뿨���������
	if ( iretu )
	{
		sprintf(ErrorInfo,"Input Fail");
		return 1;
	} 
    return 0;
}
int EnableGetdata(void)
{
	int iretu;
	iretu = OpenKeyVoic(1);
	if( iretu )
	{
		sprintf(ErrorInfo,"OpenKeyVoic Fail");
		return 1;
	}
	iretu=GetData();
	if( iretu )
	{
		sprintf(ErrorInfo,"GetData Fail");
		return 1;
	}
	return 0;
}

int CheckPressedBuf(char *pszBuff, long lTimeout)
{
	int ret;
	if (fd <= 0 )
	{
		sprintf(ErrorInfo,"Please Open Comm Port"); 
		return 1;
	}
	
	ret=read(fd, pszBuff, 1);
	if(ret != 1 )
	{
		return 1;
	}
	
	return 0;
}

int PinReadPin(char *chPin)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);
    *chPin = '\0';

    sprintf(chCommand,"%02X",0x01);
    sprintf(chCommand+2,"%02X",0x42);
    nLen = 4;
    ret = BCC( chCommand, (nLen)/2 );

    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Get PinBlock Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Get PinBlock Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+5, 16, chPin);
        chPin[8]=0;
        
    	return 0;
    }
}
int GetData(void)
{
	int  iretu;
    char  chCommand[100],chSendCmd[256];
    long  TimeCurr, TimeNow;
	int   i;
    int   nLen,ret;
    short RcvPurDataLen;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);

    sprintf(chCommand,"%02X",0x02);
    sprintf(chCommand+2,"%02X",0x45);
    sprintf(chCommand+4,"%02X",0x03);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );

    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);

	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Input Pw Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Input Pw Fail-com rcv Spc time out");
		return 1;
	}
	else
    	return 0;
}
int KeyboardClose()
{
   int  iretu;
   char  chCommand[100],chSendCmd[256];
   long  TimeCurr, TimeNow;
   int   i;
   int   nLen,ret;
   short RcvPurDataLen;
    char  buff[512] = {0};
   
   memset(chCommand,'\0',100);
   memset(chSendCmd,'\0',256);
    
   sprintf(chCommand,"%02X",0x02);
   sprintf(chCommand+2,"%02X",0x45);
   sprintf(chCommand+4,"%02X",0x00);

   nLen = strlen(chCommand);
   ret = BCC( chCommand, (nLen)/2 );
    
   sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
   iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
   if (iretu == 1)
   {
       sprintf(ErrorInfo,"Input Pw Fail-Write command to Comm faile");
       return 1;
   }
    
   iretu = KmyComRcvByDataLen(fd,buff,&i);
   if (iretu == 1)
   {
      sprintf(ErrorInfo,"Input Pw Fail-com rcv Spc time out");
      return 1;
   }
   else
      return 0;
 
}

int Encrypt(char *DataInput, char *DataOutput)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);
    *DataOutput = '\0';
    
    nLen=strlen(DataInput);
    if (nLen%16!=0)
    {
    	sprintf(ErrorInfo,"Enc Data Len Error��"); 
		return 1;
	}

    sprintf(chCommand,"%02X",nLen/2+1);
    sprintf(chCommand+2,"%02X",0x36);
	memcpy(&chCommand[4],DataInput,nLen);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Enc Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Enc Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+5, 16, DataOutput);
        DataOutput[8]=0;
        
    	return 0;
    }
}

int UnEncrypt(char *DataInput, char *DataOutput)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);
    *DataOutput = '\0';
    
    nLen=strlen(DataInput);
    if (nLen%16!=0)
    {
    	sprintf(ErrorInfo,"Dec Data Len Error��"); 
		return 1;
	}

    sprintf(chCommand,"%02X",nLen/2+1);
    sprintf(chCommand+2,"%02X",0x37);
	memcpy(&chCommand[4],DataInput,nLen);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Dec Data Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Dec Data Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+5, 16, DataOutput);
        DataOutput[8]=0;
        
    	return 0;
    }
}


int CalcMacData(char *DataInput, char *DataOutput)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);
    *DataOutput = '\0';
    
    nLen=strlen(DataInput);
    if(nLen < 5 || nLen > 200)
    {
    	sprintf(ErrorInfo,"MAC Data Len Error��"); 
		return 1;
	}

    sprintf(chCommand,"%02X",nLen/2+1);
    sprintf(chCommand+2,"%02X",0x41);
	memcpy(&chCommand[4],DataInput,nLen);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"MAC Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"MAC Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+5, 16, DataOutput);
        DataOutput[8]=0;
        
    	return 0;
    }
}

int SetEncryptMode(int iMode)		
{
	if(iMode < 0 || iMode > 1)
    {
    	sprintf(ErrorInfo,"Enc Mode Error��"); 
		return 1;
	}
	EncryptWorkMode = iMode;
	return 0;
}

int CloseComm()
{
	if (fd != 0)
	{
		close(fd);
		fd = 0;
		sprintf(ErrorInfo,"Close Port OK!");
		return 0;
	}
	else
	{
		sprintf(ErrorInfo,"The Port UnOpen!");	
		return 1;
	}
}


void geterror(char *info)
{
	memcpy(info,ErrorInfo,strlen(ErrorInfo));
	info[strlen(ErrorInfo)] = '\0';
}

/**
*@breif         main()
*/
#if 0
int mainbak(int argc, char **argv)
{
    int iRetu;
    int nread;
    char buff[512];
    
    char bBuff[10] = {0};		//���������
    int bExit; 					//�����������PINBLOCK�����־
       
    int ch;
    char cmd[30];
    int i=0;
    int iPos;
    int TmpEncryptMode = 0;		//���ܹ�����ʽ		0��DES����  1��3DES����
    
    char pWorkKeyMw[33];
    char pMaserKeyMw[33];
    char pEncryptMw[17];
    char pEncryptMwLeft[9];
    char pEncryptMwRight[9];
    
    unsigned char cInput[17];			//�����\���ܵ�����
	unsigned char cOutput[17];			//����\���ܺ������
	
	unsigned char cMacInput[17];			//�����\���ܵ�����
	unsigned char cPinLenMax[2];
    
    char cCard[20] = {0};
    
    char tmp[33];
    char tmp1[17];
    char tmp2[17];
    
    unsigned char pPinBlock[9];
    
    clock_t start, finish,internalTime;
    
    //ʹ���ն��ܹ����յ������������Ϸ���
    struct termios stored_settings;
    struct termios new_settings;
    tcgetattr (0, &stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ICANON);
    new_settings.c_cc[VTIME] = 0;
    new_settings.c_cc[VMIN] = 1;
    tcsetattr (0, TCSANOW, &new_settings);    
    
    int iMasterKeyID;
    int iWorkKeyID;
    
    char pMasterKeyID[3];
    char pWorkKeyID[3];
    
    char pMasterKey[33];
    char pWorkKey[33];
    
    while(1)
    {  
        printf("\n");
        printf("*----------------------------------------------------------------------*\n");
        printf("*                                                                      *\n");
        printf("*    ������                                                            *\n");
        printf("*           KMY 350 ���ܼ��̲��Գ���(v1.0)                             *\n");        
        printf("*                                                                      *\n");
        printf("*    1 : Open Comm                                                     *\n");
        printf("*    2 : Reset							              3 ��Reset(Clear key		 )     *\n");
        printf("*    4 : GetVer                         	5 : Getid  				           *\n");
        printf("*    A : SetDESMode      									B : SetTDESMode					     *\n");
        printf("*    C : SetPinLen(Auto len=6			 )                                   *\n");
        printf("*    6 : LoadMasterKey                                                 *\n");
        printf("*    7 : LoadWorkKey                                                   *\n");
        printf("*    8 : ActiveKey                    		                             *\n");
        printf("*    D : PinBlock						                                           *\n");
        printf("*    E : DataEnc                         F : DataDec	                 *\n");
        printf("*    G : MAC		                                                       *\n");
        printf("*    9 : Close Comm                                                    *\n");
        printf("*    0 : Exit Program                                                  *\n");
        printf("*----------------------------------------------------------------------*\n");
        printf("     Please Select(0,1,2,3,4,5,a,b,c,6,7,8,d,e,f,g,9):");
        ch = getchar();
        switch(ch)
        {
            case '0':
            	printf("\n\n");
                exit(1);
                
            case '1':
				iRetu = OpenComm();
				if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\n�򿪴��ڳɹ�\n");
				break;
                
            case '2':		//���̸�λ�Լ죨������Կ��
        		iRetu = ResetSelfCheck();
        		if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\n���̸�λ�Լ�ɹ���\n");	
                break;

			case '3':		//���̸�λ�Լ죨Ԥ����Կ��
        		iRetu = ResetAndSetPin(); 
        		if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
					printf("\n���̸�λ�Լ죨Ԥ����Կ���ɹ���\n");	
                break;
                
            case '4':		//ȡ��Ʒ�汾��
        		iRetu = GetVer(buff); 
        		if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nRev=%s\n",buff);
        			printf("\nȡ��Ʒ�汾�ųɹ���\n");		
        		}
                break;
                
            case '5':		//ȡ��Ʒ���к�
            	iRetu = GetDeviceNo(buff);
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
					printf("\nRev=%s\n",buff);
        			printf("\nȡ��Ʒ���кųɹ���\n");			
        		}
                break;
            	
            case 'A':		//���ܹ�����ʽ
            case 'a':		//���ܹ�����ʽ
            	iRetu = SetEncryptMode(0);		//0��DES����  1��3DES����
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
        			printf("\n���ü��ܹ�����ʽ��DES	�ɹ���\n");		
        		TmpEncryptMode = 0;	
                break;
                
            case 'B':		//���ܹ�����ʽ
            case 'b':
            	iRetu = SetEncryptMode(1);		//0��DES����  1��3DES����
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
        			printf("\n���ü��ܹ�����ʽ��3DES	�ɹ���\n");	
        		TmpEncryptMode = 1;			
                break;
            	
            case 'C':		//�����������볤��
            case 'c':
            	memset(cPinLenMax,'\0',2);
	            printf("\n������������������ĳ���:");
	            fgets(cPinLenMax,2,stdin);     
	                      	
	            iRetu = SetPinLen(atoi(cPinLenMax));
	            if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
					break;
				}
				else
            		printf("\n�����������볤�ȳɹ���\n");
            	break;
            	
            case '6':				//��������Կ    
        		memset(pMasterKeyID,'\0',3);
	            printf("\n��������������Կ��(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	//����Կ��	
	                      	
            	if (TmpEncryptMode==0)		//���ܹ�����ʽ��DES��ʽ
            	{
	            	memset(pMasterKey,'\0',33);
	            	printf("\n����������Կ��8λHEX��:");
	            	fgets(pMasterKey,17,stdin);               		
            		if (MainKeyDownFlag==0)		//����Կ���ط�ʽ�����ķ�ʽ(Ĭ�Ϸ�ʽ)
            		{
            			printf("\n��������Կ  ����Կ��=%d, ����Կ=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,pMasterKey) == 1)
            			{
		            		geterror(ErrorInfo);
							printf("\n %s \n ",ErrorInfo);
		            	}
            			else
        					printf("\n��������Կ  ��ʽ������ DES �ɹ���\n");	          
            		}
            		else						//����Կ���ط�ʽ�����ķ�ʽ
            		{
            			gDes(pMasterKey, pMasterKey, pMaserKeyMw);			//����Կ����
            			printf("\n��Կ���ܺ�����=%s\n",pMaserKeyMw);
            			printf("\n��������Կ  ����Կ��=%d, ����Կ=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,pMaserKeyMw)==1)
            				printf("\n��������Կ  ��ʽ������ DESʧ�ܣ�\n");
            			else
        					printf("\n��������Կ  ��ʽ������ DES�ɹ���\n");
            			
            		}
            	}
            	else							//���ܹ�����ʽ��3DES��ʽ						
            	{
	            	memset(pMasterKey,'\0',33);
	            	printf("\n ����������Կ��16λHEX��:");
	            	fgets(pMasterKey,33,stdin);               		
            		if (MainKeyDownFlag==0)		//����Կ���ط�ʽ�����ķ�ʽ
            		{
            			printf("\n��������Կ  ����Կ��=%d, ����Կ=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,pMasterKey)==1)
            			{
		            		geterror(ErrorInfo);
							printf("\n %s \n ",ErrorInfo);
		            	}
            			else
        					printf("\n��������Կ  ��ʽ������ 3DES�ɹ���\n");	          
            		}
            		else						//����Կ���ط�ʽ�����ķ�ʽ
            		{		//�ݲ���
            			memset(pEncryptMw,'\0',17);
            			printf("\n���������ص����ģ�16λASC��:");
	            		fgets(pEncryptMw,17,stdin);
	            		memset(pEncryptMwLeft,'\0',9);
	            		memset(pEncryptMwRight,'\0',9);
	            		
	            		memcpy(pEncryptMwLeft,pEncryptMw,8);
	            		memcpy(pEncryptMwRight,pEncryptMw+8,8);
	            		printf("\npEncryptMwLeft=%s\n",pEncryptMwLeft);
	            		printf("pEncryptMwRight=%s\n",pEncryptMwRight);
	            			            		
	            		gTriDes(pEncryptMwLeft, pMasterKey, tmp1);
	            		gTriDes(pEncryptMwRight, pMasterKey, tmp2);
	            		printf("tmp1=%s\n",tmp1);
	            		printf("tmp2=%s\n",tmp2);
	            		
	            		memcpy(tmp,tmp1,16);
	            		strcat(tmp,tmp2);
	            		printf("tmp=%s\n",tmp);
		
            			printf("\n��������=%s,��Կ���ܺ�����=%s\n",pEncryptMw,tmp);
            			printf("\n��������Կ  ����Կ��=%d, ����Կ=%s\n",iMasterKeyID,pMasterKey);
            			if (LoadMasterKey(iMasterKeyID,tmp) == 1)
            				printf("\n��������Կ  ��ʽ������ 3DESʧ�ܣ�\n");
            			else
        					printf("\n��������Կ  ��ʽ������ 3DES�ɹ���\n");
            			
            		}        		
            	}            		
            	break;
            	
            case '7':		//���ع�����Կ DES
        		memset(pMasterKeyID,'\0',3);
	            printf("\n��������������Կ��(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	//����Կ��
	            
	            memset(pWorkKeyID,'\0',3);
	            printf("\n���������ع�����Կ��(00,01...15):");
	            fgets(pWorkKeyID,3,stdin);  
	            
	            iWorkKeyID = atoi(pWorkKeyID);   		//������Կ�� 
            	
            	if (TmpEncryptMode == 0)				//���ܹ�����ʽ��DES��ʽ
            	{
	            	memset(pWorkKey,'\0',33);
	            	printf("\n�����빤����Կ��8λHEX ���ģ�:");
	            	fgets(pWorkKey,17,stdin);               		
					//gDes(pWorkKey, pMasterKey, pWorkKeyMw);		//��������Կ����Ϊ���ģ�����ҪDES���ܣ��õ�����
            		//printf("��Կ���ܺ�����=%s\n",pWorkKeyMw);
            		
            		printf("\n���ع�����Կ  ����Կ��=%d, ������Կ��=%d,������Կ=%s\n",iMasterKeyID,iWorkKeyID,pWorkKey);
            		
            		//if (LoadWorkKey(iMasterKeyID,iWorkKeyID,pWorkKeyMw) == 1)		//
            		if (LoadWorkKey(iMasterKeyID,iWorkKeyID,pWorkKey) == 1)
            		{
	            		geterror(ErrorInfo);
						printf("\n %s \n ",ErrorInfo);
	            		break;
	            	}
	            	else
	        			printf("\n���ع�����Կ DES�ɹ���\n");	            		
            	}
            	else						//���ܹ�����ʽ��3DES��ʽ						
            	{
            		/*
	            	memset(pMasterKey,'\0',33);
	            	printf("\n�����빤����Կ��16λHEX��:");
	            	fgets(pMasterKey,33,stdin);               		

            		memset(pEncryptMw,'\0',17);
            		printf("\n���������ص����ģ�16λASC��:");
	            	fgets(pEncryptMw,17,stdin);
	            	memset(pEncryptMwLeft,'\0',9);
	            	memset(pEncryptMwRight,'\0',9);
	            		
	            	memcpy(pEncryptMwLeft,pEncryptMw,8);
	            	memcpy(pEncryptMwRight,pEncryptMw+8,8);
	            	printf("\npEncryptMwLeft=%s\n",pEncryptMwLeft);
	            	printf("pEncryptMwRight=%s\n",pEncryptMwRight);
	            			            		
	            	gTriDes(pEncryptMwLeft, pMasterKey, tmp1);
	            	gTriDes(pEncryptMwRight, pMasterKey, tmp2);
	            	printf("tmp1=%s\n",tmp1);
	            	printf("tmp2=%s\n",tmp2);
	            		
	            	memcpy(tmp,tmp1,16);
	            	strcat(tmp,tmp2);
	            	printf("tmp=%s\n",tmp);
	            	printf("\n��������=%s,��Կ���ܺ�����=%s\n",pEncryptMw,tmp);
	            	*/
	            	memset(pWorkKeyMw,'\0',33);
	            	printf("\n�����빤����Կ���ģ�16λHEX��:");
	            	fgets(pWorkKeyMw,33,stdin); 
		
            		printf("\n���ع�����Կ  ����Կ��=%d, ������Կ��=%d,������Կ����=%s\n",iMasterKeyID,iWorkKeyID,pWorkKeyMw);
            		
            		if (LoadWorkKey(iMasterKeyID,iWorkKeyID,pWorkKeyMw) == 1)
	            	{
	            		geterror(ErrorInfo);
						printf("\n %s \n ",ErrorInfo);
	            		break;
	            	}
	            	else
	        			printf("\n���ع�����Կ 3DES�ɹ���\n");	            		      		
            	}                  	         		
            	break;    
            	
            case '8':			//�������Կ
        		memset(pMasterKeyID,'\0',3);
	            printf("\n�����뼤�������Կ��(00,01...15):");
	            fgets(pMasterKeyID,3,stdin);  
	            
	            iMasterKeyID = atoi(pMasterKeyID);   	//����Կ��
	            
	            memset(pWorkKeyID,'\0',3);
	            printf("\n�����뼤��Ĺ�����Կ��(00,01...15):");
	            fgets(pWorkKeyID,3,stdin);  
	            
	            iWorkKeyID = atoi(pWorkKeyID);   	//������Կ�� 
	                        	
            	iRetu = ActivWorkPin(iWorkKeyID, iMasterKeyID);
            	if (iRetu) 
				{
					geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
				}
				else
				{
        			printf("\n�������Կ�ɹ���\n");			
        		}
            	break;       
            	
            case 'D':
            case 'd':				//����PIN BLOCK����   
				memset(pPinBlock,'\0',9);
	            memset(cCard,'\0',20);
	            printf("\n��������ܿ��ţ�����13λASC��:");
	            fgets(cCard,20,stdin);               		

            	printf("���ܿ���=%s\n",cCard);
            	if (PinEnableMode(cCard) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
        			printf("\n����PIN BLOCK����ɹ������������룺\n");	    
        		
        		bExit = 0;
        		
        		int lTimeout = 30000;				//��ʱ�����˳�ʱ��
        		clock_t start, finish,internalTime;
				internalTime=lTimeout*1000;
				start=clock();
				
				while (!bExit)
				{
					iRetu = CheckPressedBuf(bBuff, 10);
					finish=clock();
					if((finish-start)>internalTime)
					{
						printf("���볬ʱ\n");
						break;
					}
					
					if (iRetu == 1) continue;

					switch(bBuff[0]) 
					{
						case 0x2A:		//*
							printf("%02X\n",bBuff[0]);
							bBuff[0] = 0x00;
							break;
							
						case 0x0D:		//�س�
							PinReadPin(pPinBlock);
							for (i = 0; i< 8; i++)
								printf("0x%02X ",pPinBlock[i]);
								
							bExit = 1;
							break;
							
						case 0x08:		//���
							break;
							
						case 0x1B:		//�˳�
							bExit = 1;
							printf("\n�˳�ANSI9.8����\n");
							break;
							
						default:
							bExit = 0;
							break;
					}
					if (bExit == 1) break;
				}
            	break;
            	
            case 'E':
            case 'e':				//���ݼ���    
	            memset(cInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\n������������ݣ�8λHEX��:");
	            fgets(cInput,17,stdin);               		
            	printf("\nҪ���ܵ�����=%s\n",cInput);
            	if (Encrypt(cInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\n���ݼ��ܳɹ���\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;
            	
            case 'F':
            case 'f':				//���ݽ���    
	            memset(cInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\n������������ݣ�8λHEX��:");
	            fgets(cInput,17,stdin);               		
            	printf("\nҪ���ܵ�����=%s\n",cInput);
            	if (UnEncrypt(cInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\n���ݽ��ܳɹ���\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;
            	
            case 'G':
            case 'g':				//MAC����    
	            memset(cMacInput,'\0',17);
	            memset(cOutput,'\0',17);
	            printf("\n������μ�MAC��������ݣ�HEX��:");
	            fgets(cMacInput,17,stdin);               		
            	printf("\nҪMAC���������=%s\n",cInput);
            	if (CalcMacData(cMacInput,cOutput) == 1)
            	{
            		geterror(ErrorInfo);
					printf("\n %s \n ",ErrorInfo);
            	}
            	else
            	{
            		printf("\nMAC����ɹ���\n");	
            		for (i = 0; i< 8; i++)
						printf("0x%02X ",cOutput[i]);
        		}
            	break;
                            	
            case '9':
                if (fd != 0)
                {
                    close(fd);
                    fd = 0;
                    printf("\nClose Comm Port!\n");
                }
                else
                    printf("\nAlready Close Comm Port!\n");
                break;
            default:
                break; 
        }
    }//while(1);
    
    //���˳�����ʱ�����ն˻����Ļ���
    tcsetattr (0, TCSANOW, &stored_settings);
    
}
#endif

int SetSamSlot(int iSlot)
{
	int iretu;
	char chCommand[256],chSendCmd[256];
    char buff[512];
    int Mode;
    int i;
    int nLen,ret,p;
    char pTmp[512];
    

	if( (iSlot<1) || (iSlot>4) )
	{
		sprintf(ErrorInfo,"Car No Error"); 
		return 1;
		
	}
	
    memset(chCommand,'\0',256);
    memset(chSendCmd,'\0',256);
    memset(buff,'\0',512);
    memset(pTmp,'\0',512);

    sprintf(chCommand,"%02X",0x03);
    sprintf(chCommand+2,"%02X",0x59);
    sprintf(chCommand+4,"%02X",0x01);
    sprintf(chCommand+6,"%02X",0x88);    

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
    iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Car No Error,-Write command to Comm faile"); 
		//sprintf(ErrorInfo,"Write command to Comm failed");  
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Car No Error,-com rcv by len time out");
		return 1;
	}
	else
    	return 0;
}



int SamPowerOn(char *atm,int * iLen)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);


    sprintf(chCommand,"%02X",0x01);
    sprintf(chCommand+2,"%02X",0x49);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Power On Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Power On Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+1, 2, atm);
        iretu=atm[0];
        CompressAsc(buff+5, (iretu-1)*2, atm);
        atm[iretu]=0;
        *iLen=iretu-1;
        
    	return 0;
    }
}


int SamApdu(char *apdu,char *rsp,int * iLen)
{
	int  iretu;
    char chCommand[100],chSendCmd[256];
    int nLen,ret;
    int i;
    
    char  buff[512] = {0};

    memset(chCommand,'\0',100);
    memset(chSendCmd,'\0',256);


    sprintf(chCommand,"%02X",1+strlen(apdu));
    sprintf(chCommand+2,"%02X",0x48);
    sprintf(chCommand+2+2,"%s",apdu);

    nLen = strlen(chCommand);
    ret = BCC( chCommand, (nLen)/2 );
    sprintf(chSendCmd,"%c%s%02X",0x02,chCommand,ret);
    
	iretu = KmyComSend_cmd(fd,chSendCmd,strlen(chSendCmd));
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Car Command Fail-Write command to Comm faile"); 
		return 1;
	}     
	
	iretu = KmyComRcvByDataLen(fd,buff,&i);
    if (iretu == 1)
	{
		sprintf(ErrorInfo,"Car Command Fail-com rcv by len time out");
		return 1;
	}
	else
	{
        CompressAsc(buff+1, 2, rsp);
        iretu=rsp[0];
        CompressAsc(buff+5, (iretu-1)*2, rsp);
        rsp[iretu]=0;
        *iLen=iretu-1;
        
    	return 0;
    }
}
